﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using YY.Admin.Core.Extension;

namespace YY.Admin.Core.Util
{
    public static class EnumUtil
    {
        //
        // 摘要:
        //     枚举变量是否包含指定标识
        //
        // 参数:
        //   value:
        //     枚举变量
        //
        //   flag:
        //     要判断的标识
        public static bool Has(this Enum value, Enum flag)
        {
            if (value.GetType() != flag.GetType())
            {
                throw new ArgumentException("flag", "Enumeration identification judgment must be of the same type");
            }

            ulong num = Convert.ToUInt64(flag);
            return (Convert.ToUInt64(value) & num) == num;
        }

        //
        // 摘要:
        //     设置标识位
        //
        // 参数:
        //   source:
        //
        //   flag:
        //
        //   value:
        //     数值
        //
        // 类型参数:
        //   T:
        public static T Set<T>(this Enum source, T flag, bool value)
        {
            if (!(source is T))
            {
                throw new ArgumentException("source", "Enumeration identification judgment must be of the same type");
            }

            ulong num = Convert.ToUInt64(source);
            ulong num2 = Convert.ToUInt64(flag);
            num = ((!value) ? (num & ~num2) : (num | num2));
            return (T)Enum.ToObject(typeof(T), num);
        }

        //
        // 摘要:
        //     获取枚举字段的注释
        //
        // 参数:
        //   value:
        //     数值
        public static string? GetDescription(this Enum value)
        {
            if (value == null)
            {
                return null;
            }

            FieldInfo field = value.GetType().GetField(value.ToString(), BindingFlags.Static | BindingFlags.Public);
            if (field == null)
            {
                return null;
            }

            DescriptionAttribute customAttribute = field.GetCustomAttribute<DescriptionAttribute>(inherit: false);
            if (customAttribute != null && !string.IsNullOrEmpty(customAttribute.Description))
            {
                return customAttribute.Description;
            }

            return null;
        }

        //
        // 摘要:
        //     获取枚举类型的所有字段注释
        //
        // 类型参数:
        //   TEnum:
        public static Dictionary<TEnum, string> GetDescriptions<TEnum>() where TEnum : notnull
        {
            Dictionary<TEnum, string> dictionary = new Dictionary<TEnum, string>();
            foreach (KeyValuePair<int, string> description in GetDescriptions(typeof(TEnum)))
            {
                dictionary.Add((TEnum)Enum.ToObject(typeof(TEnum), description.Key), description.Value);
            }

            return dictionary;
        }

        //
        // 摘要:
        //     获取枚举类型的所有字段注释
        //
        // 参数:
        //   enumType:
        public static Dictionary<int, string> GetDescriptions(Type enumType)
        {
            Dictionary<int, string> dictionary = new Dictionary<int, string>();
            FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public);
            foreach (FieldInfo fieldInfo in fields)
            {
                if (fieldInfo.IsStatic)
                {
                    int key = Convert.ToInt32(fieldInfo.GetValue(null));
                    string value = fieldInfo.Name;
                    DisplayNameAttribute customAttribute = fieldInfo.GetCustomAttribute<DisplayNameAttribute>(inherit: false);
                    if (customAttribute != null && !string.IsNullOrEmpty(customAttribute.DisplayName))
                    {
                        value = customAttribute.DisplayName;
                    }

                    DescriptionAttribute customAttribute2 = fieldInfo.GetCustomAttribute<DescriptionAttribute>(inherit: false);
                    if (customAttribute2 != null && !string.IsNullOrEmpty(customAttribute2.Description))
                    {
                        value = customAttribute2.Description;
                    }

                    dictionary[key] = value;
                }
            }

            return dictionary;
        }
        /// <summary>
        /// 获取操作码的查询操作枚举表示
        /// </summary>
        /// <param name="code">操作码</param>
        /// <returns></returns>
        public static FilterOperateEnum GetFilterOperate(string code)
        {
            //code.CheckNotNullOrEmpty("code");
            Type type = typeof(FilterOperateEnum);
            MemberInfo[] members = type.GetMembers(BindingFlags.Public | BindingFlags.Static);
            foreach (MemberInfo member in members)
            {
                FilterOperateEnum operate = member.Name.CastTo<FilterOperateEnum>();
                if (operate.ToOperateCode() == code)
                {
                    return operate;
                }
            }
            throw new NotSupportedException("获取操作码的查询操作枚举表示时不支持代码：" + code);
        }
        /// <summary>
        /// 把查询操作的枚举表示转换为操作码
        /// </summary>
        /// <param name="operate">查询操作的枚举表示</param>
        public static string ToOperateCode(this FilterOperateEnum operate)
        {
            Type type = operate.GetType();
            MemberInfo[] members = type.GetMember(operate.CastTo<string>());
            if (members.Length == 0)
            {
                return null;
            }

            OperateCodeAttribute attribute = members[0].GetAttribute<OperateCodeAttribute>();
            return attribute?.Code;
        }
    }
}
